using System;
using System.Collections.Generic;
using UnityEngine;

public class PlayerAnimationsController : MonoBehaviour
{
	public struct KeysInputData
	{
		public Vector3 moveDirection;

		public static KeysInputData GetNewKeysInput()
		{
			KeysInputData result = default(KeysInputData);
			result.moveDirection = Vector3.zero;
			if (Input.GetKey(KeyCode.A))
			{
				result.moveDirection.x -= 1f;
			}
			if (Input.GetKey(KeyCode.E))
			{
				result.moveDirection.x += 1f;
			}
			if (Input.GetKey(KeyCode.O))
			{
				result.moveDirection.z -= 1f;
			}
			if (Input.GetKey(KeyCode.Comma))
			{
				result.moveDirection.z += 1f;
			}
			result.moveDirection += DirectionControl.direction;
			return result;
		}
	}

	[Serializable]
	public class HitAnimationParams
	{
		public HitAnimationsStateEnum hitEnum;

		public int group;

		public bool useHitFromDB = true;

		public HitParamsDB.HitType type;

		public PlayerStatsManager.SkillType skillType;

		public float strength;

		public FloatRange strengthRange = default(FloatRange);

		public float heightAboveNet;

		public FloatRange heightAboveNetRange = default(FloatRange);

		public float spin;

		public FloatRange spinRange = default(FloatRange);

		public bool bounceOff;

		public float maxPower;

		public bool minPowerOn;

		public float minPowerAddition;

		public FloatRange hitSpeedRange = default(FloatRange);

		public float powerStrength = 0.5f;

		public float powerHeight = 0.2f;

		public bool useHeightMinMax;

		public FloatRange heightMin = default(FloatRange);

		public FloatRange heightMax = default(FloatRange);
	}

	[Serializable]
	public class ServeStartMoveParams
	{
		public ServeMoveAnimationsStateEnum startServeEnum;

		public float animationSpeed;

		public bool useMoveFromDB = true;
	}

	public class HitPlan
	{
		public HitAnimationInfo hitInfo;

		public KineticPlan.AnimSearchSolution animSearchSolution;

		public float moveAnimSpeed;

		public float hitAnimSpeed;

		public Vector3 startAnimPosition;

		public HitAnimationParams hitParams;

		public float hitFlightTime;

		public KineticPlan.HitPoint hitPoint;

		public int hitIndex;

		public float speed;

		public KineticPlan.TransformState startState;

		public Vector3 directionToHit;
	}

	protected Animator _cachedAnimator;

	public List<HitAnimationParams> hitAnimations = new List<HitAnimationParams>();

	public List<HitAnimationParams> backHitAnimations = new List<HitAnimationParams>();

	public List<ServeStartMoveParams> serveStartAnim = new List<ServeStartMoveParams>();

	public ServeStartMoveParams serveMoveLeft = new ServeStartMoveParams();

	public ServeStartMoveParams serveMoveRight = new ServeStartMoveParams();

	public ServeStartMoveParams serveGetUp = new ServeStartMoveParams();

	public ServeStartMoveParams serveWait = new ServeStartMoveParams();

	public bool useClosestAnimationIndex = true;

	[Range(0.5f, 2f)]
	public float animatorSpeed = 2f;

	[Range(1f, 20f)]
	public float maxMoveSpeed = 1.5f;

	[Range(1f, 30f)]
	public float maxJumpSpeed = 1.5f;

	public float maxMoveAnimatorSpeed = 1.5f;

	private float crossFadeDuration;

	private float maxVelocity = 4f;

	public float maxHitAnimatorSpeed = 5f;

	public bool useIK;

	public FloatRange xAdjustRange;

	public FloatRange zAdjustRange;

	public TableTennisMatchController match;

	public Animator cachedAnimator
	{
		get
		{
			if (_cachedAnimator == null)
			{
				for (int i = 0; i < base.transform.childCount; i++)
				{
					Transform child = base.transform.GetChild(i);
					_cachedAnimator = child.GetComponent<Animator>();
					if (_cachedAnimator != null)
					{
						break;
					}
				}
			}
			return _cachedAnimator;
		}
	}

	public float serveStepLeftDistance
	{
		get
		{
			MoveAnimationInfo orCreateServeMoveAnimationByEnum = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateServeMoveAnimationByEnum(serveMoveLeft.startServeEnum);
			return orCreateServeMoveAnimationByEnum.positionChange.x;
		}
	}

	public float serveStepRightDistance
	{
		get
		{
			MoveAnimationInfo orCreateServeMoveAnimationByEnum = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateServeMoveAnimationByEnum(serveMoveRight.startServeEnum);
			return orCreateServeMoveAnimationByEnum.positionChange.x;
		}
	}

	public int hitAnimationIndex { get; protected set; }

	private List<HitAnimationParams> GetHitList(GestureTracker gestureTracker)
	{
		if (Mathf.Sign(gestureTracker.CalculateFirstToLastPoint().z) == Mathf.Sign(base.transform.position.z))
		{
			return backHitAnimations;
		}
		return hitAnimations;
	}

	private List<HitAnimationParams> GetHitList(Vector3 firstToLastSwipePoint)
	{
		Vector3 vector = firstToLastSwipePoint;
		if (Mathf.Sign(vector.z) == Mathf.Sign(base.transform.position.z))
		{
			return backHitAnimations;
		}
		return hitAnimations;
	}

	public KineticElementMove GetNewKineticMoveAnimation(KineticPlan kineticPlan)
	{
		KeysInputData newKeysInput = KeysInputData.GetNewKeysInput();
		MoveAnimationInfo moveAnimInfoForKeysInput = GetMoveAnimInfoForKeysInput(newKeysInput);
		Vector3 moveOffesetForKeysInput = GetMoveOffesetForKeysInput(newKeysInput, moveAnimInfoForKeysInput);
		KineticPlanElement activeElement = kineticPlan.activeElement;
		KineticElementHit kineticElementHit = activeElement as KineticElementHit;
		if (kineticElementHit != null && kineticPlan.Count == 1 && moveAnimInfoForKeysInput != null)
		{
			KineticElementMove kineticElementMove = new KineticElementMove();
			kineticElementMove.animatorSpeed = animatorSpeed;
			kineticElementMove.animInfo = moveAnimInfoForKeysInput;
			kineticElementMove.crossFadeDuration = crossFadeDuration;
			kineticElementMove.useDesiredEnd = true;
			kineticElementMove.startFromCurrentPosition = true;
			kineticElementMove.desiredEndPosition = base.transform.position + base.transform.rotation * moveOffesetForKeysInput;
			return kineticElementMove;
		}
		if ((kineticPlan.activeElement == null || (activeElement.ellapsedTime + activeElement.animatorSpeed * GGGameTime.deltaTime >= activeElement.length && kineticPlan.Count == 1)) && kineticPlan.indexOfElementOfType<KineticElementHit>() < 0 && moveAnimInfoForKeysInput != null)
		{
			kineticPlan.CancelAllPendingElements();
			KineticElementMove kineticElementMove2 = new KineticElementMove();
			kineticElementMove2.animatorSpeed = animatorSpeed;
			kineticElementMove2.animInfo = moveAnimInfoForKeysInput;
			kineticElementMove2.crossFadeDuration = crossFadeDuration;
			kineticElementMove2.useDesiredEnd = true;
			kineticElementMove2.startFromCurrentPosition = true;
			kineticElementMove2.desiredEndPosition = base.transform.position + base.transform.rotation * moveOffesetForKeysInput;
			return kineticElementMove2;
		}
		return null;
	}

	public HitAnimationParams GetPairAnimationParams(HitAnimationInfo hitInfo)
	{
		if (hitInfo == null)
		{
			return null;
		}
		HitAnimationParams hitAnimationParams = null;
		HitAnimationParams hitAnimationParams2 = null;
		List<HitAnimationParams> list = null;
		foreach (HitAnimationParams hitAnimation in hitAnimations)
		{
			if (hitAnimation.hitEnum.ToString() == hitInfo.animatorStateName)
			{
				hitAnimationParams = hitAnimation;
				list = hitAnimations;
				break;
			}
		}
		if (hitAnimationParams == null)
		{
			foreach (HitAnimationParams backHitAnimation in backHitAnimations)
			{
				if (backHitAnimation.hitEnum.ToString() == hitInfo.animatorStateName)
				{
					hitAnimationParams = backHitAnimation;
					list = backHitAnimations;
					break;
				}
			}
		}
		if (list != null)
		{
			foreach (HitAnimationParams item in list)
			{
				if (item.group == hitAnimationParams.group && item.hitEnum != hitAnimationParams.hitEnum)
				{
					return item;
				}
			}
		}
		return null;
	}

	private MoveAnimationInfo GetMoveAnimInfoForKeysInput(KeysInputData keysInput)
	{
		MoveAnimationInfo result = null;
		if (keysInput.moveDirection.x != 0f)
		{
			result = ((!(keysInput.moveDirection.x < 0f)) ? ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetMoveAnimationByEnum(MoveAnimationsStateEnum.HopRight) : ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetMoveAnimationByEnum(MoveAnimationsStateEnum.HopLeft));
		}
		else if (keysInput.moveDirection.z != 0f)
		{
			result = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetMoveAnimationByEnum(MoveAnimationsStateEnum.HopLeftShort);
		}
		return result;
	}

	private Vector3 GetMoveOffesetForKeysInput(KeysInputData keysInput, MoveAnimationInfo animInfo)
	{
		Vector3 zero = Vector3.zero;
		if (keysInput.moveDirection.x != 0f)
		{
			zero += Vector3.right * animInfo.positionChange.x;
			zero += Vector3.forward * animInfo.zAdjustRange.LerpMinMax(keysInput.moveDirection.z * 0.5f);
		}
		else if (keysInput.moveDirection.z != 0f)
		{
			zero += Vector3.forward * animInfo.zAdjustRange.LerpMinMax(keysInput.moveDirection.z * 0.5f);
		}
		return zero;
	}

	public List<HitPlan> CreateHitPlans(GestureTracker gestureTracker, KineticPlan kineticPlan, PhysicsBall ball, float symDeltaTime, bool comeClose)
	{
		List<HitAnimationParams> hitList = GetHitList(gestureTracker);
		return CreateHitPlans(hitList, kineticPlan, ball, symDeltaTime, comeClose);
	}

	public List<HitPlan> CreateHitPlans(Vector3 firstToLastSwipePoint, KineticPlan kineticPlan, PhysicsBall ball, float symDeltaTime, bool comeClose)
	{
		List<HitAnimationParams> hitList = GetHitList(firstToLastSwipePoint);
		return CreateHitPlans(hitList, kineticPlan, ball, symDeltaTime, comeClose);
	}

	public List<HitPlan> CreateHitPlans(bool isBackHit, KineticPlan kineticPlan, PhysicsBall ball, float symDeltaTime, bool comeClose)
	{
		List<HitAnimationParams> hitList = ((!isBackHit) ? hitAnimations : backHitAnimations);
		return CreateHitPlans(hitList, kineticPlan, ball, symDeltaTime, comeClose);
	}

	private List<HitPlan> CreateHitPlans(List<HitAnimationParams> hitList, KineticPlan kineticPlan, PhysicsBall ball, float symDeltaTime, bool comeClose)
	{
		List<HitPlan> list = new List<HitPlan>();
		KineticPlan.HitPoint hitPoint = default(KineticPlan.HitPoint);
		KineticPlan.TransformState transformStateAfterAllAnimationsFinish = kineticPlan.GetTransformStateAfterAllAnimationsFinish();
		int num = -1;
		foreach (HitAnimationParams hit in hitList)
		{
			num++;
			HitAnimationInfo orCreateHitAnimationByEnum = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateHitAnimationByEnum(hit.hitEnum);
			hitPoint = KineticPlan.FindHitPointMinimizeZIncludeSpeed(ball, base.transform.position.z, symDeltaTime, orCreateHitAnimationByEnum, transformStateAfterAllAnimationsFinish.position, maxHitAnimatorSpeed, maxMoveSpeed, maxJumpSpeed, xAdjustRange, zAdjustRange);
			if (comeClose)
			{
				float num2 = ball.flightSequence.flightTime;
				FlightSequence.FlightPlanStage stageThatStartsFromTableSide = ball.flightSequence.GetStageThatStartsFromTableSide(Mathf.Sign(base.transform.position.z));
				if (stageThatStartsFromTableSide != null)
				{
					num2 = Mathf.Max(num2, stageThatStartsFromTableSide.startTime);
				}
				float num3 = hitPoint.minReachFlightTime - num2;
				float num4 = hitPoint.maxReachFlightTime - num2;
				float num5 = hitPoint.flightTimeWhenHit - num2;
				float num6 = 0.3f;
				float num7 = 0.1f;
				float value = 0.2f;
				if (num5 >= num6)
				{
					float t = 0.75f;
					float num8 = Mathf.Lerp(hitPoint.flightTimeWhenHit, hitPoint.minReachFlightTime, t);
					hitPoint.maxPosition = ball.flightSequence.PositionAt(num8);
					hitPoint.flightTimeWhenHit = num8;
					hitPoint.hitAnimationStartPosition = Vector3.Lerp(hitPoint.hitAnimationStartPosition, hitPoint.minReachPosition, t);
					hitPoint.speedToPosition = Vector3Ex.HorizontalDistance(hitPoint.hitAnimationStartPosition, transformStateAfterAllAnimationsFinish.position) / num3;
				}
				else if (num5 <= num7)
				{
					float num9 = 1f;
					num9 = Mathf.InverseLerp(num5, num4, value);
					float num10 = Mathf.Lerp(hitPoint.flightTimeWhenHit, hitPoint.maxReachFlightTime, num9);
					Vector3 vector = Vector3.Lerp(hitPoint.hitAnimationStartPosition, hitPoint.maxReachPosition, num9).OnGround();
					hitPoint.maxPosition = ball.flightSequence.PositionAt(num10);
					hitPoint.flightTimeWhenHit = num10;
					hitPoint.hitAnimationStartPosition = vector;
					hitPoint.speedToPosition = Vector3Ex.HorizontalDistance(vector, transformStateAfterAllAnimationsFinish.position) / num4;
				}
			}
			float hitAnimSpeed = maxHitAnimatorSpeed;
			if (hitPoint.foundHitPosition && hitPoint.speedToPosition == 0f)
			{
				float num11 = hitPoint.maxTime + hitPoint.stage.startTime - ball.flightSequence.flightTime;
				float num12 = num11 - transformStateAfterAllAnimationsFinish.duration;
				hitAnimSpeed = orCreateHitAnimationByEnum.hitTime / num12;
			}
			Vector3 vector2 = (hitPoint.maxPosition - transformStateAfterAllAnimationsFinish.rotation * orCreateHitAnimationByEnum.hitPosition).OnGround();
			HitPlan hitPlan = new HitPlan();
			hitPlan.speed = hitPoint.speedToPosition;
			hitPlan.hitInfo = orCreateHitAnimationByEnum;
			hitPlan.animSearchSolution = null;
			hitPlan.moveAnimSpeed = animatorSpeed;
			hitPlan.hitAnimSpeed = hitAnimSpeed;
			hitPlan.startAnimPosition = vector2;
			hitPlan.hitParams = hit;
			hitPlan.directionToHit = vector2 - transformStateAfterAllAnimationsFinish.position;
			hitPlan.hitFlightTime = hitPoint.flightTimeWhenHit;
			hitPlan.hitPoint = hitPoint;
			hitPlan.hitIndex = num;
			hitPlan.startState = transformStateAfterAllAnimationsFinish;
			list.Add(hitPlan);
		}
		return list;
	}

	public HitPlan ChooseHitPlan(List<HitPlan> hitPlans)
	{
		HitPlan hitPlan = null;
		foreach (HitPlan hitPlan2 in hitPlans)
		{
			if (hitPlan2.hitPoint.foundHitPosition && !(hitPlan2.hitAnimSpeed > maxHitAnimatorSpeed) && !(hitPlan2.hitAnimSpeed <= 0f))
			{
				if (hitPlan == null)
				{
					hitPlan = hitPlan2;
				}
				else if (hitPlan2.hitParams.group < hitPlan.hitParams.group || (hitPlan2.hitParams.group == hitPlan.hitParams.group && Mathf.Abs(hitPlan2.directionToHit.x) < Mathf.Abs(hitPlan.directionToHit.x)))
				{
					hitPlan = hitPlan2;
				}
			}
		}
		return hitPlan;
	}

	public void FillPlanForMiss(GestureTracker gestureTracker, KineticPlan kineticPlan)
	{
		List<HitAnimationParams> hitList = GetHitList(gestureTracker);
		float velx = Mathf.Sign(base.transform.position.z) * gestureTracker.CalculateFirstToLastPoint().x;
		FillPlanForMiss(hitList, velx, kineticPlan);
	}

	public void FillPlanForMiss(bool isBackHit, float velx, KineticPlan kineticPlan)
	{
		List<HitAnimationParams> hitList = ((!isBackHit) ? hitAnimations : backHitAnimations);
		FillPlanForMiss(hitList, velx, kineticPlan);
	}

	private void FillPlanForMiss(List<HitAnimationParams> hitList, float velx, KineticPlan kineticPlan)
	{
	}

	public void FillPlanForMiss(KineticPlan kineticPlan, HitPlan chosenMissPlan, PhysicsBall ball)
	{
		hitAnimationIndex = chosenMissPlan.hitIndex;
		Vector3 directionToHit = chosenMissPlan.directionToHit;
		HitAnimationInfo hitInfo = chosenMissPlan.hitInfo;
		KineticElementMoveConstant kineticElementMoveConstant = new KineticElementMoveConstant();
		kineticElementMoveConstant.desiredEndPosition = chosenMissPlan.hitPoint.hitAnimationStartPosition;
		kineticElementMoveConstant.duration = (kineticElementMoveConstant.desiredEndPosition - chosenMissPlan.startState.position).OnGround().magnitude / maxMoveSpeed;
		kineticPlan.AddElement(kineticElementMoveConstant);
		KineticElementHit kineticElementHit = new KineticElementHit();
		kineticElementHit.animInfo = hitInfo;
		kineticElementHit.useIK = useIK;
		kineticElementHit.useDesiredEnd = true;
		Quaternion rotationForHitPlan = GetRotationForHitPlan(chosenMissPlan);
		kineticElementHit.desiredEndPosition = chosenMissPlan.startAnimPosition + rotationForHitPlan * hitInfo.positionChange;
		kineticElementHit.trackFlight = null;
		kineticElementHit.animatorSpeed = chosenMissPlan.hitAnimSpeed;
		kineticElementHit.animatorSpeedAfterHit = Mathf.Clamp(1f / kineticElementHit.animatorSpeed, 0.75f, 2f);
		kineticElementHit.startFromCurrentPosition = true;
		kineticElementHit.crossFadeDuration = crossFadeDuration;
		kineticElementHit.hitPosition = chosenMissPlan.hitPoint.maxPosition;
		kineticElementHit.flightTimeWhenHit = chosenMissPlan.hitFlightTime;
		kineticElementHit.onHitDelegate = null;
	}

	public List<HitPlan> CreateMissPlans(List<HitPlan> hitPlans, KineticPlan kineticPlan, PhysicsBall ball, float symDeltaTime, bool comeClose)
	{
		List<HitPlan> list = new List<HitPlan>();
		KineticPlan.HitPoint hitPoint = default(KineticPlan.HitPoint);
		KineticPlan.TransformState transformStateAfterAllAnimationsFinish = kineticPlan.GetTransformStateAfterAllAnimationsFinish();
		foreach (HitPlan hitPlan2 in hitPlans)
		{
			if (!hitPlan2.hitPoint.foundHitPosition)
			{
				hitPoint = KineticPlan.FindClosestPointMinimizeZIncludeSpeed(ball, base.transform.position.z, symDeltaTime, hitPlan2.hitInfo, transformStateAfterAllAnimationsFinish.position, maxHitAnimatorSpeed, maxMoveSpeed, maxJumpSpeed);
				float hitAnimSpeed = maxHitAnimatorSpeed;
				if (hitPoint.foundHitPosition && hitPoint.speedToPosition == 0f)
				{
					float num = hitPoint.maxTime + hitPoint.stage.startTime - ball.flightSequence.flightTime;
					float num2 = num - transformStateAfterAllAnimationsFinish.duration;
					hitAnimSpeed = hitPlan2.hitInfo.hitTime / num2;
				}
				HitPlan hitPlan = new HitPlan();
				hitPlan.speed = hitPoint.speedToPosition;
				hitPlan.hitInfo = hitPlan2.hitInfo;
				hitPlan.animSearchSolution = null;
				hitPlan.moveAnimSpeed = animatorSpeed;
				hitPlan.hitAnimSpeed = hitAnimSpeed;
				hitPlan.startAnimPosition = hitPoint.hitAnimationStartPosition;
				hitPlan.hitParams = hitPlan2.hitParams;
				hitPlan.directionToHit = hitPoint.hitAnimationStartPosition - transformStateAfterAllAnimationsFinish.position;
				hitPlan.hitFlightTime = hitPoint.flightTimeWhenHit;
				hitPlan.hitPoint = hitPoint;
				hitPlan.hitIndex = hitPlan2.hitIndex;
				hitPlan.startState = transformStateAfterAllAnimationsFinish;
				list.Add(hitPlan);
			}
		}
		return list;
	}

	public HitPlan ChooseMissPlan(List<HitPlan> hitPlans)
	{
		HitPlan hitPlan = null;
		foreach (HitPlan hitPlan2 in hitPlans)
		{
			if (!hitPlan2.hitPoint.foundHitPosition)
			{
				if (hitPlan == null)
				{
					hitPlan = hitPlan2;
				}
				else if (hitPlan2.hitPoint.minApproachOptional < hitPlan.hitPoint.minApproachOptional)
				{
					hitPlan = hitPlan2;
				}
			}
		}
		return hitPlan;
	}

	public Quaternion GetRotationForHitPlan(HitPlan chosenHitPlan)
	{
		KineticPlan.AnimSearchSolution animSearchSolution = chosenHitPlan.animSearchSolution;
		if (animSearchSolution == null)
		{
			return chosenHitPlan.startState.rotation;
		}
		Quaternion startRotation = chosenHitPlan.animSearchSolution.startRotation;
		for (int i = 0; i < animSearchSolution.animList.Count; i++)
		{
			MoveAnimationInfo moveAnimationInfo = animSearchSolution.animList[i];
			startRotation *= moveAnimationInfo.rotationChange;
		}
		return startRotation;
	}

	public HitAnimationParams GetCurrentHitParams(GestureTracker gestureTracker)
	{
		List<HitAnimationParams> hitList = GetHitList(gestureTracker);
		return hitList[hitAnimationIndex % hitList.Count];
	}

	public void AddHitAnimation(KineticPlan kineticPlan, PhysicsBall ball, TableTennisPlayerBase player)
	{
		KineticElementHit kineticElementHit = new KineticElementHit();
		HitAnimationsStateEnum animEnum = HitAnimationsStateEnum.ForehandTopspin1;
		if (ball != null)
		{
			animEnum = ((Mathf.Sign(cachedAnimator.transform.position.x - ball.position.x) != (float)player.tableSide) ? HitAnimationsStateEnum.BackhandTopspin1Hit2 : HitAnimationsStateEnum.ForehandTopspin1);
		}
		kineticElementHit.animInfo = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateHitAnimationByEnum(animEnum);
		kineticElementHit.useIK = useIK;
		kineticElementHit.animatorSpeed = 2f;
		kineticElementHit.startFromCurrentPosition = true;
		kineticElementHit.crossFadeDuration = crossFadeDuration;
		kineticPlan.AddElement(kineticElementHit);
	}

	public void AddHitAnimation(KineticPlan kineticPlan, Vector3 directionToHit, TableTennisPlayerBase player)
	{
		KineticElementHit kineticElementHit = new KineticElementHit();
		HitAnimationsStateEnum hitAnimationsStateEnum = HitAnimationsStateEnum.ForehandTopspin1;
		hitAnimationsStateEnum = ((Mathf.Sign(directionToHit.x) == (float)player.tableSide) ? HitAnimationsStateEnum.BackhandTopspin1Hit2 : HitAnimationsStateEnum.ForehandTopspin1);
		kineticElementHit.animInfo = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateHitAnimationByEnum(hitAnimationsStateEnum);
		kineticElementHit.useIK = useIK;
		kineticElementHit.animatorSpeed = 2f;
		kineticElementHit.startFromCurrentPosition = true;
		kineticElementHit.crossFadeDuration = crossFadeDuration;
		kineticPlan.AddElement(kineticElementHit);
	}

	public void AddHitAnimation(KineticPlan kineticPlan, HitPlan chosenHitPlan, PhysicsBall ball, KineticElementHit.OnHitDelegate onHitDelegate)
	{
		hitAnimationIndex = chosenHitPlan.hitIndex;
		Vector3 directionToHit = chosenHitPlan.directionToHit;
		HitAnimationInfo hitInfo = chosenHitPlan.hitInfo;
		float num = chosenHitPlan.hitFlightTime - ball.flightSequence.flightTime - chosenHitPlan.startState.duration;
		if (num > hitInfo.hitTime)
		{
			float num2 = 1f - hitInfo.hitTime / num;
			Vector3 vector = directionToHit * num2;
			KineticElementMoveConstant kineticElementMoveConstant = new KineticElementMoveConstant();
			kineticElementMoveConstant.desiredEndPosition = chosenHitPlan.startState.position + vector;
			kineticElementMoveConstant.duration = Mathf.Min(num * num2, Vector3Ex.HorizontalDistance(kineticElementMoveConstant.desiredEndPosition, base.transform.position) / maxMoveSpeed);
			kineticPlan.AddElement(kineticElementMoveConstant);
		}
		KineticElementHit kineticElementHit = new KineticElementHit();
		kineticElementHit.animInfo = hitInfo;
		kineticElementHit.useIK = useIK;
		kineticElementHit.useDesiredEnd = true;
		Quaternion rotationForHitPlan = GetRotationForHitPlan(chosenHitPlan);
		kineticElementHit.desiredEndPosition = chosenHitPlan.startAnimPosition + rotationForHitPlan * hitInfo.positionChange;
		kineticElementHit.trackFlight = ball.flightSequence;
		kineticElementHit.animatorSpeed = chosenHitPlan.hitAnimSpeed;
		kineticElementHit.animatorSpeedAfterHit = 2f;
		kineticElementHit.startFromCurrentPosition = true;
		kineticElementHit.crossFadeDuration = crossFadeDuration;
		kineticElementHit.hitPosition = chosenHitPlan.hitPoint.maxPosition + hitInfo.racketRotationAtHit * (Vector3.back * ball.transform.localScale.z * 0.5f);
		kineticElementHit.flightTimeWhenHit = chosenHitPlan.hitFlightTime;
		kineticElementHit.onHitDelegate = onHitDelegate;
		kineticPlan.AddElement(kineticElementHit);
	}

	public void FillStartServePlan(Vector3 startServePosition, KineticPlan kineticPlan)
	{
		FillPlanWithServePosition(kineticPlan);
	}

	private void FillPlanWithServePosition(KineticPlan kineticPlan)
	{
		for (int i = 0; i < serveStartAnim.Count; i++)
		{
			ServeStartMoveParams serveStartMoveParams = serveStartAnim[i];
			MoveAnimationInfo orCreateServeMoveAnimationByEnum = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateServeMoveAnimationByEnum(serveStartMoveParams.startServeEnum);
			KineticServeMoveElement kineticServeMoveElement = new KineticServeMoveElement();
			kineticServeMoveElement.animInfo = orCreateServeMoveAnimationByEnum;
			kineticServeMoveElement.continueWithIdle = false;
			kineticServeMoveElement.startFromCurrentPosition = true;
			kineticServeMoveElement.animatorSpeed = serveStartMoveParams.animationSpeed;
			kineticServeMoveElement.crossFadeDuration = crossFadeDuration;
			kineticServeMoveElement.useDesiredEnd = false;
			kineticPlan.AddElement(kineticServeMoveElement);
		}
	}

	public void FillServeMoveLeftPlan(KineticPlan kineticPlan, bool isInCrouch, float zPos)
	{
		if (isInCrouch)
		{
			FillStandUp(kineticPlan, zPos);
		}
		FillServeMoveSideways(kineticPlan, serveMoveLeft.startServeEnum, serveMoveLeft.animationSpeed, zPos);
	}

	public void FillServeMoveRightPlan(KineticPlan kineticPlan, bool isInCrouch, float zPos)
	{
		if (isInCrouch)
		{
			FillStandUp(kineticPlan, zPos);
		}
		FillServeMoveSideways(kineticPlan, serveMoveRight.startServeEnum, serveMoveRight.animationSpeed, zPos);
	}

	private void FillServeWait(KineticPlan kineticPlan)
	{
		MoveAnimationInfo orCreateServeMoveAnimationByEnum = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateServeMoveAnimationByEnum(serveWait.startServeEnum);
		KineticPlan.TransformState transformStateAfterAllAnimationsFinish = kineticPlan.GetTransformStateAfterAllAnimationsFinish();
		KineticServeMoveElement kineticServeMoveElement = new KineticServeMoveElement();
		kineticServeMoveElement.animInfo = orCreateServeMoveAnimationByEnum;
		kineticServeMoveElement.startFromCurrentPosition = true;
		kineticServeMoveElement.animatorSpeed = serveWait.animationSpeed;
		kineticServeMoveElement.crossFadeDuration = crossFadeDuration;
		kineticServeMoveElement.useDesiredEnd = false;
		kineticPlan.AddElement(kineticServeMoveElement);
	}

	private void FillStandUp(KineticPlan kineticPlan, float zPos)
	{
		MoveAnimationInfo orCreateServeMoveAnimationByEnum = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateServeMoveAnimationByEnum(serveGetUp.startServeEnum);
		KineticPlan.TransformState transformStateAfterAllAnimationsFinish = kineticPlan.GetTransformStateAfterAllAnimationsFinish();
		KineticServeMoveElement kineticServeMoveElement = new KineticServeMoveElement();
		kineticServeMoveElement.animInfo = orCreateServeMoveAnimationByEnum;
		kineticServeMoveElement.startFromCurrentPosition = true;
		kineticServeMoveElement.animatorSpeed = serveGetUp.animationSpeed;
		kineticServeMoveElement.crossFadeDuration = crossFadeDuration;
		kineticServeMoveElement.useDesiredEnd = false;
		kineticServeMoveElement.zMoveConstraint.doConstrain = true;
		kineticServeMoveElement.zMoveConstraint.constrainThroughtoutAnim = false;
		kineticServeMoveElement.zMoveConstraint.position = zPos;
		kineticPlan.AddElement(kineticServeMoveElement);
	}

	private void FillServeMoveSideways(KineticPlan kineticPlan, ServeMoveAnimationsStateEnum moveEnum, float walkSpeed, float zPos)
	{
		MoveAnimationInfo orCreateServeMoveAnimationByEnum = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateServeMoveAnimationByEnum(moveEnum);
		KineticServeMoveElement kineticServeMoveElement = new KineticServeMoveElement();
		kineticServeMoveElement.animInfo = orCreateServeMoveAnimationByEnum;
		kineticServeMoveElement.startFromCurrentPosition = true;
		kineticServeMoveElement.animatorSpeed = walkSpeed;
		kineticServeMoveElement.crossFadeDuration = crossFadeDuration;
		kineticServeMoveElement.useDesiredEnd = false;
		kineticServeMoveElement.zMoveConstraint.doConstrain = (kineticServeMoveElement.zMoveConstraint.constrainThroughtoutAnim = true);
		kineticServeMoveElement.zMoveConstraint.position = zPos;
		kineticPlan.AddElement(kineticServeMoveElement);
		FillPlanWithServePosition(kineticPlan);
	}

	public void TossBallInAir(KineticPlan kineticPlan, float animationSpeed, KineticServeHitElement.OnHitDelegate onToss)
	{
		HitAnimationInfo orCreateServeHitAnimationByEnum = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateServeHitAnimationByEnum(ServeHitAnimationsStateEnum.ServeToss);
		kineticPlan.CancelAll(false);
		KineticServeHitElement kineticServeHitElement = new KineticServeHitElement();
		kineticServeHitElement.animInfo = orCreateServeHitAnimationByEnum;
		kineticServeHitElement.continueWithIdle = false;
		kineticServeHitElement.startFromCurrentPosition = true;
		kineticServeHitElement.animatorSpeed = animationSpeed;
		kineticServeHitElement.crossFadeDuration = 0f;
		kineticServeHitElement.useDesiredEnd = false;
		kineticServeHitElement.onHitDelegate = onToss;
		kineticPlan.AddElement(kineticServeHitElement);
	}

	public void FillServeToss(ServeHitAnimationsStateEnum hitEnum, KineticPlan kineticPlan, KineticServeHitElement.OnHitDelegate onToss, float hitTime, bool shouldWait, float optionalTimeScale = 1f)
	{
		HitAnimationInfo orCreateServeHitAnimationByEnum = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateServeHitAnimationByEnum(hitEnum);
		float num = ((!(hitTime > 0f)) ? 1.5f : (orCreateServeHitAnimationByEnum.hitTime / hitTime));
		num *= optionalTimeScale;
		KineticServeHitElement kineticServeHitElement = new KineticServeHitElement();
		kineticServeHitElement.animInfo = orCreateServeHitAnimationByEnum;
		kineticServeHitElement.continueWithIdle = false;
		kineticServeHitElement.startFromCurrentPosition = true;
		kineticServeHitElement.animatorSpeed = num;
		Debug.Log("animatorSpeed: " + num);
		kineticServeHitElement.crossFadeDuration = 0f;
		kineticServeHitElement.useDesiredEnd = false;
		kineticServeHitElement.onHitDelegate = onToss;
		kineticPlan.AddElement(kineticServeHitElement);
	}

	public void AddHitAnimation(KineticPlan kineticPlan, MStartSwipe mswipe, float symDeltaTime, PhysicsBall ball, KineticElementHit.OnHitDelegate onHitDelegate, TableTennisPlayerBase player)
	{
		try
		{
			HitAnimationsStateEnum animEnum = (HitAnimationsStateEnum)Enum.Parse(typeof(HitAnimationsStateEnum), mswipe.hitName);
			HitAnimationInfo orCreateHitAnimationByEnum = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateHitAnimationByEnum(animEnum);
			KineticPlan.TransformState transformStateAfterAllAnimationsFinish = kineticPlan.GetTransformStateAfterAllAnimationsFinish();
			float num = mswipe.timeOfhit - ball.flightSequence.flightTime - transformStateAfterAllAnimationsFinish.duration;
			if (num > orCreateHitAnimationByEnum.hitTime)
			{
				float num2 = 1f - orCreateHitAnimationByEnum.hitTime / num;
				KineticElementMoveConstant kineticElementMoveConstant = new KineticElementMoveConstant();
				kineticElementMoveConstant.desiredEndPosition = mswipe.player1Position;
				kineticElementMoveConstant.duration = Mathf.Min(num * num2, Vector3Ex.HorizontalDistance(kineticElementMoveConstant.desiredEndPosition, base.transform.position) / maxMoveSpeed);
				kineticPlan.AddElement(kineticElementMoveConstant);
			}
			else
			{
				KineticElementMoveConstant kineticElementMoveConstant2 = new KineticElementMoveConstant();
				kineticElementMoveConstant2.desiredEndPosition = mswipe.player1Position;
				kineticElementMoveConstant2.duration = Time.deltaTime;
				kineticPlan.AddElement(kineticElementMoveConstant2);
			}
			KineticPlan.HitPoint hitPoint = KineticPlan.FindHitPoint(ball, player.tableSide, symDeltaTime, orCreateHitAnimationByEnum);
			float num3 = maxHitAnimatorSpeed;
			if (hitPoint.foundHitPosition && hitPoint.speedToPosition == 0f)
			{
				float num4 = hitPoint.maxTime + hitPoint.stage.startTime - ball.flightSequence.flightTime;
				float num5 = num4 - transformStateAfterAllAnimationsFinish.duration;
				num3 = orCreateHitAnimationByEnum.hitTime / num5;
			}
			GGDebug.DebugLog("flight time: " + ball.flightSequence.flightTime + ", flight duration: " + ball.flightSequence.flightDuration + ", hit: " + mswipe.timeOfhit);
			GGDebug.DebugLog("mswipe.desiredEndPosition: " + mswipe.desiredEndPosition);
			KineticElementHit kineticElementHit = new KineticElementHit();
			kineticElementHit.animInfo = orCreateHitAnimationByEnum;
			kineticElementHit.useIK = useIK;
			kineticElementHit.useDesiredEnd = mswipe.useDesiredEndPosition;
			kineticElementHit.desiredEndPosition = mswipe.desiredEndPosition;
			kineticElementHit.trackFlight = ball.flightSequence;
			kineticElementHit.animatorSpeed = num3;
			kineticElementHit.animatorSpeedAfterHit = 2f;
			kineticElementHit.startFromCurrentPosition = true;
			kineticElementHit.crossFadeDuration = crossFadeDuration;
			kineticElementHit.hitPosition = mswipe.hitPoint;
			kineticElementHit.flightTimeWhenHit = mswipe.timeOfhit;
			kineticElementHit.onHitDelegate = onHitDelegate;
			kineticPlan.AddElement(kineticElementHit);
		}
		catch (ArgumentException)
		{
			AddHitAnimation(kineticPlan, Vector3.zero, player);
		}
	}
}
